Babel 核心基础 与 应用实践

您所在的位置:网站首页 测试json文件 转oc Babel 核心基础 与 应用实践

Babel 核心基础 与 应用实践

2023-03-25 08:39| 来源: 网络整理| 查看: 265

# Babel 核心基础 与 应用实践

TIP

本章节我们来学习 Babel 的入门知识,主要帮助大家快速掌握 Babel 是什么,及简单使用 Babel 来将 ES6 转码为(ES5 或 ES3)的代码,为后面深入学习做准备。

关于 Babel 更高级的用法(与 Webpack 的结合使用),我们在学习 Webpack 的时候再深入讲解。

本章节我们会从以下几个点来展开讲解

什么是 Babel ? 使用 Babel 在线编译器转码 Babel 的安装与使用 # 一、Babel 简介与基本使用

TIP

深入浅出 Babel 是什么,Babel 的使用方式,使用 Babel 编译 ES6 代码前后的结果 等

# 1、什么是 Babel

TIP

Babel 是一个 JavaScript 编译器,用来将 ES6 的代码转换成 ES6 之前(ES5 或 ES3)的代码。

说的直白一点,Babel 就是将新版本的代码(ES6)转换成浏览器可以兼容的 ES5 或 ES3 版本的代码,这样我们就可以放心大胆的使用 ES6 ,而不担心兼容性问题了。

关于 ES6 之后的代,其兼容性问题就交给 Babel 来处理了,Babel 可以说是 ES6 的好兄弟 !

Babel 的官网:https://babeljs.io/ (opens new window) Babel 中文网站(非官方):https://www.babeljs.cn/ (opens new window) Babel 的在线编译网址:https://babeljs.io/repl (opens new window) # 2、使用 Babel 在线编译器转码

TIP

接下来我们编写了一段简单的 ES6 代码,然后利用 Babel 的在线编译工具来编译,具体如下

注意编译器左边的勾选项

# 2.1、编译前后代码对比解析

编译前 ES6 代码如下

let username = "icoding"; const sex = "male"; const add = (x, y) => x + y; new Promise((resolve, reject) => { resolve("成功 !"); }).then((value) => { console.log(value); }); const obj = Object.assign({ a: 1 }, { b: 4 }); console.log(obj);

利用 Babel 在线编译后的代码如下

var username = "icoding"; var sex = "male"; var add = function add(x, y) { return x + y; }; new Promise(function (resolve, reject) { resolve("成功 !"); }).then(function (value) { console.log(value); }); var obj = Object.assign({ a: 1 }, { b: 4 }); console.log(obj);

编译解析:

Babel 转码后,let 和 const 转换成了 var,箭头函数转换成了普通函数。 但 Promise、Object.assign()编译后,并没有做任何的修改,还是原样输出了

原因是:

Babel 只能编译 ES6 的大部分语法(如:let、const、class、()=>箭头函数这些类似新增的语法),但对于 ES6 新增的 API(如:Set、Map、Promise、Array.from()、Object.assign())本身默认是没有办法通过 Babel 编译来转换成 ES5 之前的语法的。 因为语法的转换很简单,直接替换就完事。但像 Promise 等这些新增的全局对象,并没有办法直接替换,除非再实现一份,否则是无法转换的。 所以要解决 ES6 新增的 API,我们只能人为的去实现这些 API 方法,说的直白一点就是在当前代码中通过 ES5 版本的 JS 来手动实现Promise、Set、Map等方法。当然这些方法不需要我们自己去写,官方帮我们实现了,我们只需要引入第三方对应的 JS 模块就可以了。 # 2.2、引入 polyfill

TIP

能过前面的学习,我们知道 Babel 只能编译 ES6 的大部分语法,对 ES6 新的 API 本身是没有办法转的。所以我们需要通过引入第三方模块来解决代码(目标环境-浏览器)中缺失的 API。

polyfill翻译为中文为"垫片",所谓的”垫片“,是指垫平不同浏览器之间差异的东西。比如我们上面提到的,在低版本浏览器中不支持 ES6 的大部分语法,所以polyfill提供了 ES6 中新增的所有 API。通过在我们的项目中引入polyfill就可以补全浏览器缺失的 API。

在 bootcdn 网站上,搜索 babel 官方提供的 polyfill,搜索名字为babel-polyfill,具体如下

代码经过 Babel 转码后,我们再在项目中,手动引入polyfill.min.js文件,如下

var username = "icoding"; var sex = "male"; var add = function add(x, y) { return x + y; }; new Promise(function (resolve, reject) { resolve("成功 !"); }).then(function (value) { console.log(value); }); var obj = Object.assign({ a: 1 }, { b: 4 }); console.log(obj);

注:

为了测试效果,可以安装低版本的浏览器来测试,以下是firefox浏览器所有版本的 下载地址 (opens new window)

我下载的是 firefox32 版来测试,在 firefox32.0 版中,是不支持Object.assign()方法的,这个方法从 firefox34.0 版开始支持。

以上代码在没有引入polyfill前,在 firefox32 中没有会抛出错误TypeError: Object.assign is not a function,引入后,则正常输出结果。

在实际的项目开发中

我们肯定不会手动的在编译好的代码中来引入 polyfill,因为这种方式会把当前代码中没有用到的 ES6API 全都加载进来了,这样项目的体积就太大了。我们希望能实现按需加载(也就是只加载当前项目中用到的 ES6 API)

后面我们会结合 Webpack 来实现按需引入。

# 3、Babel 的安装与使用

TIP

上面使用 Babel 的在线编译是为了让大家能快速的了解 Babel,在实际开发中,我们肯定不会利用在线编译来转码,而是通过安装 Babel 来实现转码。

Babel 有哪些使用方式,在官网中即可查看 https://babeljs.io/setup (opens new window)

习惯性通过官网查看学习,毕竟最新的使用方式也会实时更新和升级(避免现在学习了,未来又会有新的变化)

这里我们先来学习使用 Babel 的 CLI 命令行工具来实现转码,具体如下

注:

Babel 的使用方式非常多以上 官方链接 (opens new window)中都是,我们常见的会使用 CLI 命令行工具 或 在 Webpack 中使用。

当我们点击任意使用方式,即可跳转至 对应的使用步骤,按步骤操作即可

# 3.1、Babel 的安装

TIP

首先新建项目目录文件夹,所有 Babel 都是安装在当前项目下 则在项目录下执行npm init -y 初始化项目(生成package.json文件) 执行下面命令,安装 Babel 相关的两个包,安装成 开发依赖 # 我们可以通过运行以下命令在本地安装 Babel CLI # 注:以下命令会默认安装最新版本的 babel # @babel/core Babel 的所有核心功能都在这里 # @babel/cli 是Babel命令行转码工具,如果我们想在通过命令进行Babel转码,就需要安装它,如:在终端通过命令 npx babel...或 npm run bulid 来实现转码 npm install --save-dev @babel/core @babel/cli

在实际开发中

不会每次都使用最新版本,毕竟是第三的包,我们无法控制。如果官方升级,有可能语法也会变化,就会导致项目报错而无法运行,这也是非常常见的情况。

所以大家在学习时,可以参考我现在版本,安装时带上对应的版本号。

安装成功后,会在package.json文件中的devDependencies 属性中,添加如下两个字段

"devDependencies": { // 提供了 CLI 命令,用来执行 babel 相关命令 "@babel/cli": "^7.21.0", // babel 的核心包,用来发号施令调度用的,不做具体的事情,具体怎么做交给其他包来完成 "@babel/core": "^7.21.3" }

温馨提示:

可以在安装前,执行npm view @babel/core versions 来查其所有版本

Babel 相关的包安装好之后,接下来创建项目目录和需要转码的 JS 代码,然后利用 Babel 命令来转码。

# 3.2、创建目录和对应的 ES6 代码

TIP

转码前,在当前目录下新建src目录,然后在src目录下新建main.js文件 把需要转码的代码放在main.js文件中

代码如下

let username = "icoding"; const sex = "male"; const add = (x, y) => x + y; new Promise((resolve, reject) => { resolve("成功 !"); }).then((value) => { console.log(value); }); const obj = Object.assign({ a: 1 }, { b: 4 }); console.log(obj); # 3.3、在 package.json 文件中添加执行的 babel 命令

TIP

接下来,在package.json文件的scripts属性中,新增"build": "babel src -d dist"

"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "babel src -d dist" }

scripts 属性解析

scripts属性用于存放通过npm run命令来执行的命令。 通过在命令行中输入npm run build 就相当于是执行后面的babel src -d dist,那你可能会想,那我直接把babel src -d dist命令在终端执行,为什么会报错呢?这个问题,我们放在后面来给大家讲。 test用于测试使用,可以删除,也可以保留。

"build": "babel src -d dist" 命令解读

build:构建创建的意思,这个名字可以自己取,主要用于 npm run build 时来执行后面的babel src -d dist命令 babel:表示编译执行的是 babel 命令 src:表示将 src 目录下的所有 JS 文件进行编译(用于存放需要编译的 ES6 文件),也可以指定单独的某个 JS 文,如:babel src/main.js -d dist -d:表示输出,-d 是 --out-dir 的缩写,表示输出目录的意思 dist:表示编译后的文件输出到 dist 目录下,这个文件夹的名字可以自定义

当我们执行上面的命令后,在当前目录下生成了 dist 目录,同时在目录中有main.js文件

编译结果

以上编译后的代码,仔细观察会发现,只是将格式调整了下,又原文输出了 !本质上么有发生任何变化。

转码失败原因

原因是,缺少了 Babel 的配置文件,我们要能实现 ES6 编译成兼容 ES5 或 ES3 的代码,需要在 Babel 的配置文件中配置相关信息(指定编译规则),告诉 Babel 把 ES6 编译成兼容 ES5 还是 ES3 的代码。 如果我们不指定具体将 ES6 的代码编译成兼容 ES5 的,还是 ES3 等,那 Babel 也不知道要如何转,所以他就会原样输出我们的代码。 # 3.4、创建 Babel 配置文件 babel.config.json

TIP

Babel 的配置文件是执行 Babel 时默认在当前目录下搜寻的文件,主要有.babelrc、.babelrc.js、babel.config.json、package.json。它们的配置项都是相同的,作用也是一样的的,只需要选择其中一种即可。

接下来我们在根目录中创建一个babel.config.json配置文件并启用一些 预设。我们可以使用env 预设,该预设为 ES2015+ 启用转换(本质:如何将所有 ES6 转换成 ES5,具体转换规则的方法都在这个包里)。

具体配置如下:

{ "presets": ["@babel/preset-env"] }

关于预设的理解

预设可以理解为一组插件的集合,我们想要把 ES6 代码转换成 ES5 或 ES3 的代码,需要用到的插件非常多,而预设相当于是把这些需要用到的插件放到了一个包里,我们只需要安装这个包,然后利用这个包里的插件来帮我们实现对应的转码工作。

在 Babel 6 时期,有年代预设,比如

babel-preset-es2015 ES2015 标准中的语法转换器预设 babel-preset-es2016 ES2016 标准中的语法转换器预设 babel-preset-es2017 ES2017 标准中的语法转换器预设 .......

现在没有年代预设了,而是把所有预设打包到一起为@balel/preset-env 中,至后新增的语法需要转换,对应的插件也会更新到这个包中,所以我们现在只需要配置这一个预设就可以。

配置后,我们还需要安装@babel/preset-env包,执行以下命令即可

# @babel/preset-env 包只是告诉babel我们如何把ES6转成ES5,转码后,项目上线并不需要这个包,所以安装成开发依赖 npm install @babel/preset-env --save-dev

安装完成后,可在 package.json 文件中查看@babel/preset-env 的配置依赖信息,如下

"devDependencies": { // 提供了 CLI 命令,用来执行 babel 相关命令 "@babel/cli": "^7.21.0", // babel 的核心包,用来发号施令调度用的,不做具体的事情,具体怎么做交给其他包来完成 "@babel/core": "^7.21.3", // 这个包提供了ES6转ES5的语法转换规则,用来告诉 babel 具体该如何将ES6转ES5 "@babel/preset-env": "^7.20.2" }

注:

你可能会想,明明每次 Babel 转码都需要安装三个包,为什么还要把他们拆分,然后分别安装呢 ?

其实这就是模块化开发思想,这样模块化拆分,每一个包的分工都会非常的明确,需要什么就用什么(避免用不到的都统统引入项目,造成资源的浪费)

# 3.5、再次执行编译命令

以上配置好后,我们接下来再次执行以下命令来编译

npm run build

注:

这一次终于成功了,恭喜你,你已经学会了如何使用 Babel 来实现转码。不过上面 ES6 新增的 API 目前还是实现不了,只能通过手动引入Polyfill来补全。

等我们后面学到Webpack时,我们就可以通过Webpack来实现安需引入空缺的 API。

# 二、总结:Babel 转码流程

TIP

我们利用 Babel 来转码,需要经过以下 7 个步骤

①、创建项目的根目录,如 icoding 新建文件夹 ②、在根目录,利用npm init -y来初始化项目,创建package.json文件 ③、把需要转码的 JS 文件(main.js)放在当前目录的src目录下(目录名可以自定义) ④、执行以下命令,一次安装 Babel 需要的包,安装成开发依赖 npm install --save-dev @babel/core @babel/cli @babel/preset-env ⑤、在根目录下创建babel.config.json配置文件,配置以下信息 { "presets": ["@babel/preset-env"] } ⑥、在package.json中添加执行 babel 的命令,这样我们就可以通过npm run build命令来执行 babel 命令完成转码。 "scripts": { "build": "babel src -d dist" } ⑦、最后在当前目录终端执行以下命令,完成转码 npm run build

注:

不过 Babel 只能编译 ES6 的大部分语法,但对于 ES6 新增的 API 是没有办法转的。我们只能通过引入 polyfill 来补全缺失的 API,这样我们的项目就可以在不同版本的浏览器上运行,而不用担心兼容性问题。

不过手动引入 polyfill 会造成我们的 JS 文件过大,因为我们可能只用了部分的 ES6 新特性,但我们把所有缺失的新特性都添加进来了。

这个问题,我们后面学了 Webpack 再来解决。

# 1、npm run build 背后到底做了什么 ?

TIP

在package.json中通过配置以下信息,就可以通过npm run build命令来执行 babel 了。

"scripts": { "build": "babel src -d dist" }

我们说npm run build就相当于是执行了babel src -d dist,那为什么我们直接在命令终端输出babel src -d dist命令会报错呢 ?

原因在于

当我们执行npm run build时, 他会默认找到node_modules/.bin/下的 babel,也就是node_modules/.bin/babel ,打开这个文件,文件内容如下

#!/bin/sh basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") case `uname` in *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; esac if [ -x "$basedir/node" ]; then exec "$basedir/node" "$basedir/../@babel/cli/bin/babel.js" "$@" else exec node "$basedir/../@babel/cli/bin/babel.js" "$@" fi

上面的 babel 文件中,相当于执行了以下命令

node C:/Users/EDY/Desktop/test/icoding/node_modules/@babel/cli/bin/babel.js src -d dist # 我们在命令行执行上面命令,也可以实现同样的转码效果 # 在当前目录下,上面命令可以简写成如下 node .\node_modules\@babel\cli\bin\babel.js src -d dist

总结:

我们把命令配置在 package.json 中,这样在每次执行相同命令时,就可以达到减化输入的命令。

# 2、npx 命令

TIP

npx 是新版的 Node.js 里附带的命令,我们也可能通过在当前目录的命令终端执行以下代码,来实现转码。

npx 的功能和 npm 类似,他在运行时,也会默认找到node_modules/.bin/下面 babel 来执行

npx babel src -d dist

这里我们来补充种写法

# 将当目录下的src目录中的main.js文件转码后,在当前目录下生成转码成功后bundle.js文件 npx babel .\src\main.js -o bundle.js # -o 右侧是编译后js的存放位置,不过不会自动创建文件,需要手动把文件夹新建好 npx babel .\src\main.js -o .\dist\bundle.js 上次更新时间: 3/21/2023, 1:07:17 AM

← 系统常用命令、Node.js 与 npm、开发自己的 npm 包 Webpack5 核心基础、入口 entry 与 出口 output →

大厂最新技术学习分享群

微信扫一扫进群,获取资料

X


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3